
#region Import Namespaces
using System;
using System.Collections;
using System.Data;
using SqlClient=System.Data.SqlClient;

using BO = PHSRAG.Insight21.BusinessObjects;
using Utility = PHSRAG.Utility;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;
using DataAccess = PHSRAG.Utility.DataAccess;
#endregion

namespace PHSRAG.Insight21.Humans
{
	/// <summary>
	/// This object will contain the adddition request raised for the Drug/Device.
	/// -->Loads the addition request.
	/// -->Saves the addition request.
	/// -->Deletes the addition request.
	/// Additional features:
	///		-->Accept() deletes the addition request in the insight database (meaning that the drug/device is accepted and added to the legacy database)
	///		-->Reject() deletes the addition request as well as the entry in the legacy database.(Meaning the drug/device addition request is rejected)
	/// </summary>
	public class ListAdditionRequest:BO.SmartBusinessObject
	{
		#region constructors
		/// <summary>
		/// Constructs a new object(ListAdditionRequest) based on the cache policy passed in as a parameter. 
		/// </summary>
		/// <param name="cachePolicy">available cahche policy</param>
		public ListAdditionRequest(ICachePolicy cachePolicy) : base(cachePolicy)
		{
			
		}
		/// <summary>
		/// Constructs a new ListAdditionRequest object based on the Cache Policy  and the datarow passed in as a parameter. 
		/// All the instance variables will be set to the values from the datarow.
		/// </summary>
		/// <param name="cachePolicy">Available cache Policy</param>
		/// <param name="dataRow">Datarow passsed in </param>
		public ListAdditionRequest(ICachePolicy cachePolicy,DataRow row) : base(cachePolicy)
		{
			PopulateDataMembers(row);
		}

		/// <summary>
		/// Constructs a new object with the values passed in as parameters
		/// </summary>
		/// <param name="cachePolicy">The prevalent cache policy</param>
		/// <param name="category">Category</param>
		/// <param name="rexId">Rex Id</param>
		/// <param name="itemName">Name of the item</param>
		/// <param name="processId">Process Id</param>
		public ListAdditionRequest(ICachePolicy cachePolicy, string category, string rexId, string itemName, int processId) : base(cachePolicy)
		{
			this.category = category;
			this.rexId = rexId;
			name = itemName;
			protocolProcessId = processId;
			dirty = true;
		}
		#endregion

		#region private instance variables
		private string category=string.Empty;
		private string rexId=string.Empty;
		private string name=string.Empty;
		private string protocolNumber=string.Empty;
		private string title = string.Empty;
		private int protocolProcessId=0;
		private int protocolId=0;
		private string submitter=string.Empty;
		private DateTime dateCreated;
		#endregion

		#region private constants
		private const string ColumnAdditionRequestId = "Id";
		private const string ColumnAdditionRequestCategory="Category";
		private const string ColumnAdditionRequestRexId="RexId";
		private const string ColumnAdditionRequestName="Name";
		private const string ColumnAdditionRequestProtocolNumber="ProtocolNumber";
		private const string ColumnAdditionRequestProtocolTitle = "Title";
		private const string ColumnAdditionRequestPPId = "ProtocolProcessId";
		private const string ColumnAdditionRequestProtocolId="ProtocolId";
		private const string ColumnAdditionRequestDateCreated="DateCreated";
		private const string ColumnAdditionRequestSubmitter="Submitter";
		#region cacheKey
			private const string AdditionRequestKey = "AdditionRequestKey_6CFDB3D8-4CE8-49f6-945F-94C76EDF0D2B";
		#endregion
		#endregion
	
		#region public properties
		/// <summary> Gets/Sets the Category of the addition request</summary>
		public string Category
		{
			get{return category;}
			set { SetDirty( ref category,value);}
		}
		/// <summary> Gets/Sets the RexId </summary>
		public string RexId
		{
			get{return rexId;}
			set { SetDirty( ref rexId,value);}
		}
		/// <summary> Gets/Sets the Name </summary>
		public string Name
		{
			get{return name;}
			set{ SetDirty( ref name,value);}
		}
		/// <summary> Gets the Protocol Number </summary>
		public string ProtocolNumber
		{
			get{return protocolNumber;}
		}
		/// <summary>
		/// Gets the long title of the Protocol
		/// </summary>
		public string Title
		{
			get { return title; }
			set { SetDirty(ref title, value); }
		}
		/// <summary>Get the truncated title of the protocol</summary>
		public string TruncatedTitle
		{
			get
			{
				string longTitle = Title;
				return (longTitle.Length > Constants.MaxTitleLength) ? (longTitle.Substring(0, Constants.MaxTitleLength - 3) + "...") : longTitle;
			}
		}
		/// <summary> Gets/Sets the ProtocolProcessId </summary>
		public int ProtocolProcessId
		{
			get{return protocolProcessId;}
			set{ SetDirty(ref protocolProcessId,value);}
		}
		/// <summary> Gets the ProtocolId </summary>
		public int ProtocolId
		{
			get{return protocolId;}
		}
		/// <summary> Gets the Submitter </summary>
		public string Submitter
		{
			get{return submitter;}
		}
		/// <summary> Gets the date on which the addition request was raised </summary>
		public DateTime DateCreated
		{
			get{return dateCreated;}
		}
		/// <summary>
		/// Cache Key uniquely identifies this object within the cache.
		/// </summary>
		/// <returns>the unique string for this object.</returns>
		public override string CacheKey()
		{
			return AdditionRequestKey;
		}
		#endregion
				
		#region caching
		/// <summary>
		/// Cache the current object(ListAdditionRequest) using the prevalent cache policy.
		/// </summary>
		public override void Cache()
		{
			CachePolicy.Cache(AdditionRequestKey, this);
		}

		/// <summary>
		/// Remove the current object(ListAdditionRequest) from the cache using the prevalent cache policy.
		/// </summary>
		public override void UnCache()
		{
		CachePolicy.UnCache(AdditionRequestKey);
		}
		#endregion

		#region protected override methods
		/// <summary>Load the ListAdditionRequest based on the specified Id</summary>
		/// <param name="connectionString">Database connection string</param>
		/// <param name="args"> Addition request Id</param>
		public override void Load(string connection, params object[] args)
		{
			try
			{
				if (args.Length != 1)
				{
					throw new Exception("Load() of listAdditionRequest object requires only Id as parameter");
				}
				else 
				{
					DataTable dataTable = DataAccess.GetDataTable(connection, "GetListAdditionRequest",
						DataAccess.BuildSqlParameterArray("Id", SqlDbType.Int, (int)args[0]));
					if((dataTable!=null) && (dataTable.Rows.Count!=0))
					{
						PopulateDataMembers(dataTable.Rows[0]);
					}
				}						
			}
			catch(Exception ex)
			{
				throw new Exception("Failed to load Addition request. Error occurred while trying to execute the Load()", ex);
			}
		}
		/// <summary>Saves the addition request item</summary>
		/// <param name="sqlTransaction">DB Transaction to use during deletion.</param>
		protected override void SaveObject(SqlClient.SqlTransaction sqlTransaction)
		{
			try
			{
				Id=Convert.ToInt32( DataAccess.ExecuteScalar(sqlTransaction.Connection,sqlTransaction,"UpdateListRequest", 
					DataAccess.BuildSqlParameterArray(
					"@id",				  SqlDbType.Int,		Id,
					"@category",		  SqlDbType.VarChar,	category,
					"@rexId",			  SqlDbType.VarChar,	rexId,
					"@name",			  SqlDbType.VarChar,	name,
					"@protocolProcessId", SqlDbType.VarChar,	protocolProcessId
					)));
			}
			catch(Exception ex)
			{
				throw new Exception("Failed to save additionRequest. Error occurred while executing the SaveObject() of ListAdditionRequest object", ex);
			}
		}
	
		/// <summary>
		/// Deletes the addition request. 
		/// </summary>
		/// <param name="sqlTransaction">DB Transaction to use during deletion.</param>
		protected override void DeleteObject(SqlClient.SqlTransaction sqlTransaction)
		{
			try
			{
				DataAccess.ExecuteNonQuery( sqlTransaction.Connection, sqlTransaction,"RemoveListRequest", 
					DataAccess.BuildSqlParameterArray( "@id", SqlDbType.Int, Id ));
			}
			catch(Exception ex)
			{
				throw new Exception("Failed to delete additionRequest. Error occurred while executing the DeleteObject() of ListAdditionRequest object", ex);
			}	
		}
		#endregion

		#region public Methods
		/// <summary>
		/// Deletes the addition request from the insight database (meaning the Drug/Device had been accepted and added to the legacy database)
		/// </summary>
		/// <param name="connection">Insight connection string</param>
		public void Accept(string connection)
		{
			try{Delete(connection);}
			catch(Exception ex)
			{
				throw new Exception("Failed to delete the addition request from Insight. Error occurred while trying to execute the Accept() of ListAdditionRequest object", ex);
			}
		}

		/// <summary>
		/// Deletes the addition request from the insight and the legacy database (meaning the Drug/Device is rejected from getting added to the legacy database)
		/// </summary>
		/// <param name="conn">Legacy connection string</param>
		/// <param name="conn">Insight connection string</param>
		public void Reject(string rexConnection,string conn)
		{
			SqlClient.SqlConnection connection = new SqlClient.SqlConnection(conn);
			SqlClient.SqlTransaction transaction = null;
			try
			{	
				connection.Open();
				transaction = connection.BeginTransaction( System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
				Delete(transaction);
				DeleteRexEntry(rexConnection);
				transaction.Commit();
			}
			catch( Exception ex )
			{				
				if( transaction != null )
				{
					transaction.Rollback();
					throw new Exception("Failed to delete the addition request from the Insight and legacy database. Error occurred while trying to execute the Reject() of ListAdditionRequest object", ex);
				}
			}
			finally
			{
				if (connection.State != ConnectionState.Closed)
				connection.Close();
			}
		}
		#endregion

		#region private methods
		/// <summary>
		/// Deletes the Drug/Device from the legacy database.
		/// </summary>
		/// <param name="rexConnection">legacy database connection string</param>
		private void DeleteRexEntry(string rexConnection)
		{
			try
			{
				DataAccess.ExecuteNonQuery(rexConnection,"spDrugDeviceMaintDelete", 
					DataAccess.BuildSqlParameterArray("@nItemCode", SqlDbType.Int, rexId));
			}
			catch(Exception ex)
			{
				throw new Exception("Failed to delete the entry from Rex. Error occurred while trying to execute the DeleteRexEntry() of ListAdditionRequest object", ex);
			}
		}

		/// <summary>
		/// Sets the data members of the object(ListAdditionRequest)
		/// </summary>
		/// <param name="additionRequestRow">DataRow containing the values for the data members  </param>
		private void PopulateDataMembers(DataRow additionRequestRow)
		{
			try
			{
				Id = (int)additionRequestRow[ColumnAdditionRequestId];
				object o = additionRequestRow[ColumnAdditionRequestCategory];
				category = (o == DBNull.Value)? string.Empty:o.ToString();
				o = additionRequestRow[ColumnAdditionRequestRexId];
				rexId = (o == DBNull.Value)?string.Empty:o.ToString();
				o = additionRequestRow[ColumnAdditionRequestName];
				name =(o == DBNull.Value)?string.Empty:o.ToString();
				o = additionRequestRow[ColumnAdditionRequestProtocolNumber];
				protocolNumber = (o == DBNull.Value)?string.Empty:o.ToString();

				if (additionRequestRow.Table.Columns.Contains(ColumnAdditionRequestProtocolTitle))
				{
					title = additionRequestRow[ColumnAdditionRequestProtocolTitle].ToString();
				}
				
				o=additionRequestRow[ColumnAdditionRequestPPId];
				protocolProcessId =(o == DBNull.Value)? 0:(int)o;
				o=additionRequestRow[ColumnAdditionRequestProtocolId];
				protocolId =(o == DBNull.Value)? 0:(int)o;
				dateCreated =(System.DateTime)additionRequestRow[ColumnAdditionRequestDateCreated];
				o = additionRequestRow[ColumnAdditionRequestSubmitter];
				submitter = (o == DBNull.Value)?string.Empty:o.ToString();
			}
			catch(Exception ex)
			{
				throw new Exception("Failed to populate the data members. Error occurred while trying to execute the PopulateDatemembers() of ListAdditionRequest object", ex);
			}
		}
		#endregion

	}
}
